﻿namespace BadHabit.Factory.Controls {
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Shapes;

    /// <summary>
    /// Represents a generic panel, that keeps track whenever the application should
    /// or should not request data to the webservice.
    /// </summary>
    public class GenericPanel : UserControl {


        private bool NeedToRequestData { get; set; }


        /// <summary>
        /// Gets and Sets the control that has trigered a bind
        /// and lately was canceled by the user.
        /// </summary>
        protected object CancelChangeControlSender { get; set; }

        


        /// <summary>
        /// Gets the panel DataContext as a ProjectDataSet.
        /// </summary>
        public Data.ProjectDataSet DataContextAsProjectDataSet {
            get {
                return DataContext as Data.ProjectDataSet;
            }
        }

        /// <summary>
        /// Gets the panel DataContext as a ProjectDataSet.
        /// </summary>
        public Data.ProjectDataSet.ProjectRow Project {
            get {
                if (DataContextAsProjectDataSet != null && DataContextAsProjectDataSet.Project.Count>0) {
                    return DataContextAsProjectDataSet.Project[0];
                }
                return null;
            }
        }

        /// <summary>
        /// Default constructor.
        /// </summary>
        public GenericPanel() {
            this.Visibility = Visibility.Hidden;
            DataContextChanged += new DependencyPropertyChangedEventHandler(GenericPanel_DataContextChanged);
            Loaded += new RoutedEventHandler(GenericPanel_Loaded);
        }

        /// <summary>
        /// Every time the panel was loaded, verifies if is there a need for request the data.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GenericPanel_Loaded(object sender, RoutedEventArgs e) {

            if (!IsEnabled)
                return;

            if (NeedToRequestData)
                CallRequestData();

        }

        /// <summary>
        /// Everytime the datacontext changes, calls UpdateDataContext and sets the panel to visible.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void GenericPanel_DataContextChanged(object sender, DependencyPropertyChangedEventArgs e) {
            Data.ProjectDataSet dsProject = e.NewValue as Data.ProjectDataSet;            

            // hides the panel if no project was found at the context
            if (dsProject!=null && dsProject.Project.Count > 0)
                this.Visibility = Visibility.Visible;
            else
                this.Visibility = Visibility.Hidden;

            NeedToRequestData = true;

        }

        public bool IsSelected {
            get {
                return (Client.FactoryMainWindow.SelectedTabItem.Content == this);
            }
        }
        
        public void CallRequestData() {


              if(RequestData())
                NeedToRequestData = false;


        }

        /// <summary>
        /// This should overwrited.
        /// </summary>
        /// <returns></returns>
        protected virtual bool RequestData() {        
            return true;
        }


        /// <summary>
        /// Verifies if the task dataset has been changed since the last apply
        /// and if the user is ok in lost them.
        /// 
        /// In case of the change had been called by a list control, it also
        /// unselected the list control item if the user if affraid to lost the data.
        /// </summary>
        /// <param name="sender">The control that triggered the bind</param>
        /// <param name="previusItem">The previous selection of the control</param>
        /// <returns>True if has no change made or if the user agrees in lost them</returns>
        public bool CanLostChanges(object sender, object previusItem) {

            // no change to lost
            if(!HasChanges)
                return true;

            // ask the user for lost changes
            MessageBoxResult d = Views.Error.ShowDialog(
                global::BadHabit.Factory.Windows.Properties.Resources.Dicard_changes_continue, global::BadHabit.Factory.Windows.Properties.Resources.Discard_Changes,
                 MessageBoxButton.YesNo, MessageBoxImage.Question, MessageBoxResult.No );
            

            // if the guy is brave, so lost them
            if (d == MessageBoxResult.Yes)
                return true;

            // if is a chicken and was a combobox or list, then unselect the change
            System.Windows.Controls.Primitives.Selector selector = sender as System.Windows.Controls.Primitives.Selector;
            if (selector != null) {
                CancelChangeControlSender = selector;
                selector.SelectedItem = previusItem;
                CancelChangeControlSender = null;
            }

            return false;

        }

        /// <summary>
        /// Returns true if the panel has unsaved changes.
        /// Should be overwritten for each panel logic.
        /// </summary>
        public virtual bool HasChanges {
            get {
                return false;
            }
        }


        protected void Save_CanExecute(object sender, CanExecuteRoutedEventArgs e) {
            if (Client.FactoryMainWindow == null)
                e.CanExecute = false;
            else
                e.CanExecute = Client.FactoryMainWindow.ProjectHasChanges;
            e.Handled = true;
        }

        protected void Save_Executed(object sender, ExecutedRoutedEventArgs e) {
            Client.FactoryMainWindow.Save();
        }



    }
}
